#include "main.h"

sqlite3*db=NULL;//数据库描述符
pthread_mutex_t pm1;//互斥锁
time_t now;
int epoll_listen0,epoll_listen1;//TCP监听列表
int main(int argc, const char *argv[])
{
	//初始化数据库
	if(INIT_DB(&db,&now)==-1)return -1;
	int ret;
	//建立本机IP、port信息结构体
	struct sockaddr_in addr={0};
	addr.sin_family=AF_INET;
	addr.sin_port=htons(6666);
	addr.sin_addr.s_addr=inet_addr("0.0.0.0");


	//***********************TCP***********************
	//创建套接字描述符
	int S;
	if((S=socket(AF_INET,SOCK_STREAM,0))==-1){perror("创建TCP套接字失败");return -1;}
	if(bind(S,(struct sockaddr*)&addr,sizeof(addr))==-1){perror("绑定本机TCP失败");return -1;}
	listen(S,10);
	//***************************************************


	//***********************epoll***********************
	epoll_listen0=epoll_create(EPOLL_CLOEXEC);
	epoll_listen1=epoll_create(EPOLL_CLOEXEC);
	printf("epoll_listen0=%d\nepoll_listen1=%d\n",epoll_listen0,epoll_listen1);
	struct epoll_event epoll_data={0};epoll_data.events=EPOLLIN;
	epoll_data.data.fd=S;//加入服务器描述符
	epoll_ctl(epoll_listen0,EPOLL_CTL_ADD,S,&epoll_data);
	epoll_data.data.fd=0;//加入标准输入描述符
	epoll_ctl(epoll_listen0,EPOLL_CTL_ADD,0,&epoll_data);
	//创建监听返回数组
	struct epoll_event epoll_buf[2]={0};
	//***************************************************


	//*********************客户端数据**********************
	int C;//客户端描述符//read返回值//返回客户端
	struct sockaddr_in client_addr={0};
	int client_addr_len=sizeof(client_addr);
	struct client_login_data user_login={0};
	//***************************************************
	

	//*********************创建线程***********************
	//初始化互斥锁
	pthread_mutex_init(&pm1,NULL);
	//pthread_mutex_init(&pm2,NULL);
	pthread_t server_tcp;
	if(ret=pthread_create(&server_tcp,NULL,server_TCP_fun,NULL)!=0){printf("创建TCP线程失败:%d\n",ret);return -1;}
	//**************************************************
	

	while(1)//接收客户端数据
	{

		printf("\n阻塞等待客户端连接请求...");fflush(stdout);
		int len=epoll_wait(epoll_listen0,epoll_buf,2,-1);
		for(int i=0;i<len;i++)
		{
			if(epoll_buf[i].data.fd==S)
			{
				int to_data=0;
				C=accept(S,(struct sockaddr*)&client_addr,&client_addr_len);
				if(C==-1){perror("与客户端建立连接失败");break;}
				printf("##客户端<%s>建立连接\n",inet_ntoa(client_addr.sin_addr));
				ret=read(C,&user_login,sizeof(struct client_login_data));
				if(ret==-1){perror("读取客户端信息失败");to_data=-4;goto top1;}
				if(ret==0){printf("##客户端<%s>断开连接\n",inet_ntoa(client_addr.sin_addr));to_data=-4;goto top1;}
				//查询客户端账号
				struct user_data test_data={0};
				printf("查找账号<%s>密码<%s>在数据库的信息为:\n",user_login.userID.name,user_login.userID.password);
				if(inquire1_DB(db,user_login.userID.name,0,&test_data)==-1){printf("查询数据库失败\n");to_data=-4;goto top1;}
				//
				//****************************************登陆*****************************************
				if(user_login.type==1)
				{
					//0:登陆成功
					//-1:账号不存在
					//-2:密码错误
					//-3:已登陆
					//-4:登陆失败
					if(strcmp(test_data.name,user_login.userID.name)==0 && strcmp(test_data.password,user_login.userID.password)==0)//账号密码正确
					{
						if(test_data.C!=0)//已登陆
							to_data=-3;
						else//未登陆
						{
							//更新数据库
							test_data.C=C;
							strcpy(test_data.IP,inet_ntoa(client_addr.sin_addr));test_data.TP=time(NULL);
							int edit1_DB_ret=edit1_DB(db,3,test_data);
							//加入监听列表
							epoll_data.data.fd=C;//加入标准输入描述符
							int epoll_ctl_ret=epoll_ctl(epoll_listen1,EPOLL_CTL_ADD,C,&epoll_data);
							if( epoll_ctl_ret!=0 || edit1_DB_ret!=0 )
							{
								epoll_ctl(epoll_listen1,EPOLL_CTL_DEL,C,&epoll_data);
								edit1_DB(db,2,test_data);
								to_data=-4;
							}
							else
							{
								printf("##客户端<%s>添加连接\n",inet_ntoa(client_addr.sin_addr));
								to_data=0;
							}
						}
					}
					else if(strcmp(test_data.name,user_login.userID.name)==0 && strcmp(test_data.password,user_login.userID.password)!=0)//密码错误
						to_data=-2;
					else if(strlen(test_data.name)==0)//账号不存在
						to_data=-1;
					else
						to_data=-4;
				}
				//
				//****************************************注册*****************************************
				else if(user_login.type==2)
				{
					
					//0:注册成功
					//-1:账号已存在
					//-2;注册失败
					if(strlen(test_data.name)==0)//不存在
					{
						//添加到数据库
						printf("添加到数据库\n");
						strcpy(test_data.name,user_login.userID.name);strcpy(test_data.password,user_login.userID.password);
						test_data.C=C;strcpy(test_data.IP,inet_ntoa(client_addr.sin_addr));test_data.TP=time(NULL);
						if(edit1_DB(db,1,test_data)!=0)
							to_data=-2;
						else
						{
							printf("客户端注册成功\n");
							to_data=0;
						}
					}
					else
						to_data=-1;
				}
				//****************************************反馈客户端*****************************************
				top1:
				printf("反馈客户端<ret=%d\n",to_data);
				write(C,&to_data,4);
				if(user_login.type!=1||to_data!=0)
				{
					close(C);
					printf("##客户端<%s>断开连接\n",inet_ntoa(client_addr.sin_addr));
				}
				
			}
			//
			//********************************************键盘输入*****************************************
			else if(epoll_buf[i].data.fd==0)
			{
				char buf[128]={0};
				scanf("%127s",buf);
				while(getchar()!=10);
				printf("获取标准输入流输入:%s",buf);
			}
		}
	}
	//退出系统
	return 0;
}
